package pl.edu.agh.neuraleconomy.common.configuration;

import java.io.FileInputStream;
import java.util.Properties;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;

public class Configuration {
	private static Logger logger = Logger.getLogger(Configuration.class);
	private static final String fileUrl = ".\\application.properties";

	private static Properties props = new Properties();

	private static String dbConnectionUrl = "jdbc:postgresql://localhost:5432/postgres?user=postgres&password=postgres";

	private static int[] networkStructure = { 9, 11, 0, 1 };

	private static Double advisorRoc = 1.0;
	private static Double advisorRsi = 0.0;
	private static Double advisorEma = 0.0;
	private static Double advisorPrediction = 0.0;

	private static Integer rocPeriod = 5;
	private static Integer rsiPeriod = 5;
	private static Integer emaPeriod = 13;

	static {
		FileInputStream fis = null;

		try {
			fis = new FileInputStream(fileUrl);
			props.load(fis);
			logger.info("Configuration loaded successfully");
		} catch (Exception e) {
			logger.fatal("Cannot load configuration", e);
		} finally {
			IOUtils.closeQuietly(fis);
		}

	}

	public static Integer getRsiPeriod() {
		return getIntProp("rsi.period", rsiPeriod);
	}

	public static Integer getEmaPeriod() {
		return getIntProp("ema.period", emaPeriod);
	}

	public static Integer getRocPeriod() {
		return getIntProp("roc.period", rocPeriod);
	}

	public static Double getAdvisorPrediction() {
		return getDoubleProp("advisor.prediction", advisorPrediction);
	}

	public static Double getAdvisorEma() {
		return getDoubleProp("advisor.ema", advisorEma);
	}

	public static String getConnectionUrl() {
		return props.getProperty("dbConnectionUrl", dbConnectionUrl);
	}

	public static int[] getNetworkStructure() {
		String prop = props.getProperty("networkStructure");

		try {
			if (prop != null) {
				String[] split = prop.split(",");
				if(split.length < 4){
					throw new IllegalArgumentException("Network structure to short");
				}
				
				int [] res = new int[4];
				
				for(int i = 0; i< res.length; i++){
					res[i] = Integer.parseInt(split[i]);
				}
				
				if(res[3] != 1){
					throw new IllegalArgumentException("Output layer must be length of 1");
				}
				
				return res;
			}
		} catch (Exception e) {
			logger.error("", e);
			return networkStructure;
		}
		
		return networkStructure;
	}

	public static Double getAdvisorRoc() {
		return getDoubleProp("advisor.roc", advisorRoc);
	}

	public static Double getAdvisorRsi() {
		return getDoubleProp("advisor.rsi", advisorRsi);
	}

	private static Double getDoubleProp(String key, Double defaultValue) {
		String prop = props.getProperty(key);

		if (prop != null) {
			return Double.parseDouble(prop);
		}

		return defaultValue;
	}

	private static Integer getIntProp(String key, Integer defaultValue) {
		String prop = props.getProperty(key);

		if (prop != null) {
			return Integer.parseInt(prop);
		}

		return defaultValue;
	}

}
